﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Validation;
using System.Linq;
using System.Web;

namespace HMS.Data
{
    public class AppointmentService
    {
        public List<Doctor_Location> GetDoctorList(int LocId)
        {
            HMSEntities dt = new HMSEntities();
            var lstDoctorLoc = dt.Doctor_Location.Where(x => x.Loc_Id == LocId).ToList();
            return lstDoctorLoc;
        }

        public List<Location> GetLocationList(string clinicCode)
        {
            HMSEntities dt = new HMSEntities();
            var lstLocation = dt.Locations.Where(x => x.Clinic.Clinic_Code == clinicCode).ToList();
            return lstLocation;
        }

        public List<Doctor_Appointment> GetAppointmentDetails(int patientId, int DoctorId)
        {
            HMSEntities dt = new HMSEntities();
            var currentDate = DateTime.UtcNow.AddHours(5).AddMinutes(30);
            return dt.Doctor_Appointment.Where(x => x.Patient_Id == patientId && x.Doctor_Location.Doctor.Doc_Id == DoctorId).OrderByDescending(x => x.Doc_Appt_Date_Time).ToList<Doctor_Appointment>();
            //return doctorApptDetails;
        }

        public List<Doctor_Appointment> GetAppointmentByDocIdLocId(int DocId, int LocId, int clinicId, DateTime startDate, DateTime endDate)
        {

            HMSEntities dt = new HMSEntities();
            var _docLocId = dt.Doctor_Location.Where(x => x.Doc_Id == DocId && x.Loc_Id == LocId).FirstOrDefault();
            var _lstAppointments = dt.Doctor_Appointment.Where(x => x.Doc_Loc_Id == _docLocId.Doc_Loc_Id &&
                x.Doctor_Location.Location.Loc_Clinic_Id == clinicId
                && x.Doc_Appt_Date_Time >= startDate
                && x.Doc_Appt_Date_Time <= endDate
                && x.IsDeleted == false).ToList();
            return _lstAppointments;
        }

        public Doctor_Appointment SaveAppointmentDetails(Doctor_Appointment doctor_Appt, string clinicCode)
        {
            string patientCode = string.Empty;
            if (doctor_Appt.Patient.Patient_id != 0)
            {
                using (var dt = new HMSEntities())
                {
                    try
                    {
                        Patient patient = dt.Patients.Find(doctor_Appt.Patient.Patient_id);
                        //patient.Patient_id = doctor_Appt.Patient.Patient_id;
                        patient.Patient_Name = doctor_Appt.Patient.Patient_Name;
                        patient.Patient_Gender = doctor_Appt.Patient.Patient_Gender;
                        patient.Patient_DOB = doctor_Appt.Patient.Patient_DOB;
                        patient.Patient_Allergies = doctor_Appt.Patient.Patient_Allergies;
                        patient.Patient_Phone = doctor_Appt.Patient.Patient_Phone;
                        patient.Patient_Email = doctor_Appt.Patient.Patient_Email;
                        patient.Patient_Clinic_Id = doctor_Appt.Patient.Patient_Clinic_Id;

                        patient.Modified_By = 1;
                        patient.Modified_Date = DateTime.Now;
                        patient.Modified_Date = doctor_Appt.Patient.Modified_Date;
                        dt.SaveChanges();
                        doctor_Appt.Patient = patient;
                        doctor_Appt.Patient_Id = patient.Patient_id;
                    }
                    catch (DbEntityValidationException e)
                    {
                        foreach (var eve in e.EntityValidationErrors)
                        {
                            Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                                eve.Entry.Entity.GetType().Name, eve.Entry.State);
                            foreach (var ve in eve.ValidationErrors)
                            {
                                Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                    ve.PropertyName, ve.ErrorMessage);
                            }
                        }
                        throw;
                    }
                    catch (Exception ex)
                    {
                        throw new Exception();
                    }
                }
            }
            using (var dt = new HMSEntities())
            {
                try
                {

                    patientCode = doctor_Appt.Patient.Patient_Name.Substring(0, 3) + "0000";
                    doctor_Appt.Patient.Patient_Access_Code = clinicCode + "P" + patientCode;
                    if (doctor_Appt.Patient.Patient_id != 0)
                        doctor_Appt.Patient = null;
                    dt.Doctor_Appointment.Add(doctor_Appt);
                    dt.SaveChanges();
                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    throw;
                }
            }
            if (!string.IsNullOrEmpty(patientCode) && doctor_Appt.Patient != null)
            {
                using (var dt = new HMSEntities())
                {
                    try
                    {
                        Patient patient = dt.Patients.Find(doctor_Appt.Patient.Patient_id);
                        patientCode = ("0000" + doctor_Appt.Patient.Patient_id);
                        patientCode = patientCode.Substring(patientCode.Length - 4, 4);
                        patientCode = doctor_Appt.Patient.Patient_Name.Substring(0, 3).ToUpper() + patientCode;
                        patient.Patient_Access_Code = clinicCode + "-P-" + patientCode;
                        dt.SaveChanges();
                    }
                    catch (DbEntityValidationException e)
                    {
                        foreach (var eve in e.EntityValidationErrors)
                        {
                            Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                                eve.Entry.Entity.GetType().Name, eve.Entry.State);
                            foreach (var ve in eve.ValidationErrors)
                            {
                                Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                    ve.PropertyName, ve.ErrorMessage);
                            }
                        }
                        throw;
                    }
                }
            }

            //using ()
            //{
            var dataContext = new HMSEntities();
            return dataContext.Doctor_Appointment.Find(doctor_Appt.Doc_Appt_Id);
            //}
        }


        public int UpdateAppointmentDetails(Doctor_Appointment doctor_Appt)
        {
            bool isPatientChanged = false;
            int savedCount = 0;
            using (var dt = new HMSEntities())
            {
                Doctor_Appointment existingDocAppt = dt.Doctor_Appointment.Find(doctor_Appt.Doc_Appt_Id);
                try
                {
                    existingDocAppt.Doc_Loc_Id = doctor_Appt.Doc_Loc_Id;
                    if (existingDocAppt.Patient_Id == doctor_Appt.Patient.Patient_id)
                    {
                        existingDocAppt.Patient.Patient_Name = doctor_Appt.Patient.Patient_Name;
                        existingDocAppt.Patient.Patient_Gender = doctor_Appt.Patient.Patient_Gender;
                        existingDocAppt.Patient.Patient_DOB = doctor_Appt.Patient.Patient_DOB;
                        existingDocAppt.Patient.Patient_Allergies = doctor_Appt.Patient.Patient_Allergies;
                        existingDocAppt.Patient.Patient_Phone = doctor_Appt.Patient.Patient_Phone;
                        existingDocAppt.Patient.Patient_Email = doctor_Appt.Patient.Patient_Email;
                        existingDocAppt.Patient.Patient_Clinic_Id = doctor_Appt.Patient.Patient_Clinic_Id;
                    }
                    else
                    {
                        existingDocAppt.Patient_Id = doctor_Appt.Patient.Patient_id;
                        isPatientChanged = true;
                    }
                    existingDocAppt.Doc_Appt_Date_Time = doctor_Appt.Doc_Appt_Date_Time;
                    existingDocAppt.Doc_Appt_Follow_Up = doctor_Appt.Doc_Appt_Follow_Up;
                    existingDocAppt.Doc_Purpose = doctor_Appt.Doc_Purpose;
                    existingDocAppt.Doc_Appt_Status_Id = doctor_Appt.Doc_Appt_Status_Id;
                    existingDocAppt.Modified_By = 1;
                    existingDocAppt.Modified_Date = DateTime.Now;
                    existingDocAppt.Modified_Date = doctor_Appt.Modified_Date;
                    savedCount = dt.SaveChanges();
                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    throw;
                }
                catch (Exception ex)
                {
                    throw new Exception();
                }
            }
            if (isPatientChanged)
            {
                using (var dt = new HMSEntities())
                {
                    Patient patient = dt.Patients.Find(doctor_Appt.Patient.Patient_id);
                    patient.Patient_Name = doctor_Appt.Patient.Patient_Name;
                    patient.Patient_Gender = doctor_Appt.Patient.Patient_Gender;
                    patient.Patient_DOB = doctor_Appt.Patient.Patient_DOB;
                    patient.Patient_Allergies = doctor_Appt.Patient.Patient_Allergies;
                    patient.Patient_Phone = doctor_Appt.Patient.Patient_Phone;
                    patient.Patient_Email = doctor_Appt.Patient.Patient_Email;
                    patient.Patient_Clinic_Id = doctor_Appt.Patient.Patient_Clinic_Id;
                    patient.Modified_By = 1;
                    patient.Modified_Date = DateTime.Now;
                    patient.Modified_Date = doctor_Appt.Patient.Modified_Date;
                    savedCount = dt.SaveChanges();
                }

            }
            return savedCount;
        }
        public Clinic GetClinicName(string clinicCode)
        {
            using (var dt = new HMSEntities())
            {
                var clinic = dt.Clinics.Where(x => x.Clinic_Code == clinicCode).FirstOrDefault();
                if (clinic == null)
                    clinic = dt.Clinics.Take(1).FirstOrDefault();
                return clinic;
            }

        }

        public bool DeleteAppointment(int AppointmentId)
        {
            using (var dt = new HMSEntities())
            {
                var _apptdocument = dt.Appointment_Document.Where(x => x.Doc_Appt_Id == AppointmentId).ToList();
                if (_apptdocument != null)
                {
                    foreach (var item in _apptdocument)
                    {
                        dt.Appointment_Document.Remove(item);
                        dt.SaveChanges();
                    }
                }

                var _doctorAppointment = dt.Doctor_Appointment.Where(x => x.Doc_Appt_Id == AppointmentId).FirstOrDefault();
                if (_doctorAppointment != null)
                {
                    dt.Doctor_Appointment.Remove(_doctorAppointment);
                    dt.SaveChanges();
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        public List<USP_GetPatientName_Result> GetPatientName(string patientName, int ClinicId)
        {
            List<USP_GetPatientName_Result> lstPatient = new List<USP_GetPatientName_Result>();
            using (var dt = new HMSEntities())
            {
                lstPatient = dt.USP_GetPatientName(patientName, ClinicId).ToList<USP_GetPatientName_Result>();
            }
            return lstPatient;
        }

        public Patient GetPatientByPatientId(int PatientId)
        {

            using (var dt = new HMSEntities())
            {
                return dt.Patients.Where(x => x.Patient_id == PatientId).FirstOrDefault();
            }
        }

        public Doctor_Appointment GetPatientAppointmentByPatientId(int patientId,DateTime date)
        {
            using (var dt = new HMSEntities())
            {
                var currentDateTime = DateTime.UtcNow.AddHours(5).AddMinutes(30);
                return dt.Doctor_Appointment.Where(x => x.Patient_Id == patientId && x.Doc_Appt_Date_Time < date).OrderByDescending(x => x.Doc_Appt_Date_Time).FirstOrDefault();
            }
        }

        public Appointment_Document SaveImage(Appointment_Document appointment_Document)
        {

            Appointment_Document appDoc = new Appointment_Document();
            using (var dt = new HMSEntities())
            {
                var appointment = dt.Doctor_Appointment.Where(x => x.Doc_Appt_Id == appointment_Document.Doc_Appt_Id).FirstOrDefault();
                appDoc.Doc_Appt_Id = appointment.Doc_Appt_Id;
                appDoc.Doctor_Appointment = dt.Doctor_Appointment.Where(x => x.Doc_Appt_Id == appointment_Document.Doc_Appt_Id).FirstOrDefault();
                appDoc.Appt_Image_Name = appointment_Document.Appt_Image_Name;
                appDoc.Created_By = 1;
                appDoc.Created_Date = DateTime.Now;
                appDoc.Modified_By = 1;
                appDoc.Modified_Date = DateTime.Now;
                dt.Appointment_Document.Add(appDoc);
                dt.SaveChanges();
            }
            return appDoc;
        }

        public List<USP_GetImagesbyDocApptId_Result> GetImagesList(int docApptId)
        {
            List<USP_GetImagesbyDocApptId_Result> lstPatient = new List<USP_GetImagesbyDocApptId_Result>();
            using (var dt = new HMSEntities())
            {
                lstPatient = dt.USP_GetImagesbyDocApptId(docApptId).ToList<USP_GetImagesbyDocApptId_Result>();
            }
            return lstPatient;
        }

        public Doctor GetDoctorByDocId(int DocId)
        {
            Doctor doc = new Doctor();
            using (var dt = new HMSEntities())
            {
                doc = dt.Doctors.Where(x => x.Doc_Id == DocId).FirstOrDefault();
            }
            return doc;
        }

        public List<Doctor_Appointment> GetAppointmentHistoryByPatientId(int patientId, int numberOfRecord)
        {
            //using ()
            //{
            var dt = new HMSEntities();
            //return dt.Doctor_Appointment.Where(x => x.Patient_Id == patientId).OrderByDescending(x => x.Modified_Date).Take(numberOfRecord).ToList<Doctor_Appointment>();
            var appointments = dt.Doctor_Appointment.Where(x => x.Patient_Id == patientId).ToList<Doctor_Appointment>();
            return appointments.OrderByDescending(x => x.Modified_Date).Take(numberOfRecord).ToList<Doctor_Appointment>();
            //}
        }

        public Appointment_Document SavePatientImage(Appointment_Document appointment_Document)
        {

            Appointment_Document appDoc = new Appointment_Document();
            using (var dt = new HMSEntities())
            {
                var appointment = dt.Doctor_Appointment.Where(x => x.Patient_Id == appointment_Document.Patient_Id).FirstOrDefault();
                appDoc.Patient_Id = appointment.Patient_Id;
                appDoc.Patient = dt.Patients.Where(x => x.Patient_id == appointment_Document.Patient_Id).FirstOrDefault();
                appDoc.Appt_Image_Name = appointment_Document.Appt_Image_Name;
                appDoc.Created_By = 1;
                appDoc.Created_Date = DateTime.Now;
                appDoc.Modified_By = 1;
                appDoc.Modified_Date = DateTime.Now;
                dt.Appointment_Document.Add(appDoc);
                dt.SaveChanges();
            }
            return appDoc;
        }

        public List<Doctor_Slot> GetDoctorSlots(int DocId)
        {
            using (var dt = new HMSEntities())
            {
                
                return dt.Doctor_Slot.Where(x => x.Doc_Id == DocId).ToList<Doctor_Slot>();
              
            }
        }

        public Doctor_Appointment GetAppointmentById(int DocApptId)
        {
            Doctor_Appointment doc = new Doctor_Appointment();
            using (var dt = new HMSEntities())
            {
                doc = dt.Doctor_Appointment.Where(x => x.Doc_Appt_Id == DocApptId).FirstOrDefault();
            }
            return doc;
        }

        public Doctor_Location GetDocLocByDocLocId(int DocLocid)
        {
            Doctor_Location docLoc = new Doctor_Location();
            using (var dt = new HMSEntities())
            {
                docLoc = dt.Doctor_Location.Where(x => x.Doc_Loc_Id == DocLocid).FirstOrDefault();
            }
            return docLoc;
        }

        public List<Doctor_Appointment> GetAppointbyPatientId(int PatientId)
        {
            List<Doctor_Appointment> lstAppt = new List<Doctor_Appointment>();
            using (var dt = new HMSEntities())
            {
                lstAppt = dt.Doctor_Appointment.Where(x => x.Patient_Id == PatientId).ToList<Doctor_Appointment>();
            }
            return lstAppt;
        }

        public Clinic GetClinicByLocId(int LocId)
        {
            using (var dt = new HMSEntities())
            {
                var ClinicId = dt.Locations.Where(x => x.Loc_Id == LocId).FirstOrDefault().Loc_Clinic_Id;
                return dt.Clinics.Where(x => x.Clinic_Id == ClinicId).FirstOrDefault();
            }
        }

        public bool SavePrescriptionText(Appointment_Document appDoc)
        {
            using (var dt = new HMSEntities())
            {
                try
                {
                    var _apptDoc = dt.Appointment_Document.Add(appDoc);
                    dt.SaveChanges();
                    return true;
                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    return false;
                }
 
            }

        }

        public bool SaveDoctorDayOff(Doctor_DayOff docSlot) {
            using (var dt = new HMSEntities())
            {
                try
                {
                    dt.Doctor_DayOff.Add(docSlot);
                    dt.SaveChanges();
                    return true;
                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    return false;
                }
 
            }
        }

        public List<Doctor_DayOff> getDoctorDayOff(Doctor_DayOff docSlot) {
            using (var dt = new HMSEntities())
            {
                return dt.Doctor_DayOff.Where(x => x.Doc_Id == docSlot.Doc_Id).ToList();
            }
        }

        public bool DeleteDoctorDayOff(Doctor_DayOff docSlot)
        {
            using (var dt = new HMSEntities())
            {
                try
                {
                    var _docSlot = dt.Doctor_DayOff.Where(x => x.Doc_Day_Off == docSlot.Doc_Day_Off.Date && x.Doc_Id == docSlot.Doc_Id).FirstOrDefault();
                    if (_docSlot != null) {
                        
                        //dt.Doctor_Slot.Attach(_docSlot);
                        dt.Doctor_DayOff.Remove(_docSlot);
                        dt.SaveChanges();
                        return true;
                    }
                    return false;
                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    return false;
                }

            }
        }

        public List<Doctor_DayOff> getDoctorDayOffByDocIdDate(int DocId,DateTime date)
        {
            using (var dt = new HMSEntities())
            {
                DateTime _date1 = date.Date;
                return dt.Doctor_DayOff.Where(x => x.Doc_Id == DocId && x.Doc_Day_Off == _date1).ToList();
            }
        }

    }
}